<template>
  <ckeditor
    :editor="editor"
    v-model="editorData"
    :config="editorConfig"
    :disabled="readonly"
    @ready="onEditorReady"
  />
</template>

<script setup name="Editor">
import { ref, computed, watch, nextTick } from 'vue'
import { merge, mergeWith, isArray, debounce } from 'lodash-es'
import { Ckeditor } from '@ckeditor/ckeditor5-vue'
import { InlineEditor } from '@rev-ai/ckeditor5-classic'

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  config: {
    type: Object,
    default: () => ({})
  },
  readonly: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits([
  'update:modelValue',
  'update:readonly',
  'ready',
  'focus',
  'blur',
  'tableChange'
])

let editorInstance = null
const editor = InlineEditor
const defaultConfig = {
  language: 'zh-cn',
  toolbar: {
    items: [
      'heading',
      'blockQuote',
      '|',
      'bold',
      'underline',
      'italic',
      'strikethrough',
      '|',
      'fontColor',
      'fontBackgroundColor',
      'fontSize',
      'fontFamily',
      'removeFormat',
      '|',
      'alignment',
      'bulletedList',
      'numberedList',
      'outdent',
      'indent',
      '|',
      'link',
      'insertTable',
      'imageInsert',
      'mediaEmbed',
      'undo',
      'redo'
    ]
  },
  balloonToolbar: {
    items: [
      'bold',
      'italic',
      '|',
      'alignment:left',
      'alignment:center',
      'alignment:right',
      '|',
      'fontColor'
    ],
    shouldNotGroupWhenFull: true
  },
  htmlSupport: {
    allow: [
      {
        name: /.*/,
        attributes: true,
        classes: true,
        styles: true
      }
    ]
  },
  image: {
    toolbar: [
      'imageTextAlternative',
      'toggleImageCaption',
      'imageStyle:inline',
      'imageStyle:block',
      'imageStyle:side',
      'linkImage'
    ]
  },
  mediaEmbed: {
    toolbar: ['mediaEmbed']
  },
  table: {
    contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells']
  },
  allowedContent: {
    img: {
      attributes: '!src, alt', // src is required
      styles: 'height, width, position, left, top'
    }
  }
}
const editorConfig = computed(() => {
  return mergeConfig(defaultConfig, props.config)
})
const editorData = computed({
  get: function () {
    return props.modelValue
  },
  set: function (value) {
    emit('update:modelValue', value)
  }
})
const mergeConfig = (obj, other) => {
  return Object.assign({}, obj, other)
}
// 表格非内容变化事件（合并、拆分单元格、新增、删除行列、调整列宽）
const debounceTableChange = debounce(function (results) {
  if (results.length) {
    const firstResult = results[0]
    emit('tableChange', {
      ...firstResult,
      action: firstResult.type === 'attribute' ? firstResult.attributeKey : firstResult.type,
      name: firstResult.name,
      type: firstResult.type,
      results
    })
  }
}, 100)
let editorInitialContent = '' // 保存获取焦点时的内容
const onEditorReady = (editor) => {
  emit('ready', editor)
  editorInstance = editor
  editor.ui.focusTracker.on('change:isFocused', (evt, name, isFocused) => {
    if (!isFocused) {
      // 编辑器失去焦点时触发
      // console.log('编辑器失去焦点')
      const currentContent = editor.getData()
      const hasChanged = currentContent !== editorInitialContent
      emit('blur', editor.getData(), hasChanged)
      editorInitialContent = ''
      // 在这里执行你的逻辑，比如自动保存、验证内容等
    } else {
      // 编辑器获得焦点时触发
      // console.log('编辑器获得焦点')
      editorInitialContent = editor.getData()
      emit('focus', editor.getData())
    }
  })
  nextTick(() => {
    // @keydown.enter.prevent 禁用编辑器中的回车
    editor.editing.view.document.on(
      'keydown',
      (evt, data) => {
        if (data.keyCode === 13) {
          // 回车键
          // 阻止所有相关行为
          evt.stop()
          data.preventDefault()
          data.stopPropagation()
          return false
        }
      },
      { priority: 'highest' }
    )
    // 表格非内容变化事件（合并、拆分单元格、新增、删除行列、调整列宽）
    editor.model.document.on('change:data', () => {
      const changes = editor.model.document.differ.getChanges()
      let allTableChanges = []
      changes.forEach((change) => {
        if (change.type === 'insert' || change.type === 'remove') {
          // 获取变更位置所在的父元素
          const parent = change.position.parent

          // 检查是否在表格内（table/tablerow/tablecell）
          if (
            parent.is('element', 'table') ||
            parent.is('element', 'tableRow') ||
            parent.is('element', 'tableCell')
          ) {
            // console.log('表格发生修改:', change)
            // 记录变更细节（如时间、操作类型等）
            allTableChanges.push(change)
            debounceTableChange(allTableChanges)
          }
        } else if (change.type === 'attribute' && change.attributeKey === 'columnWidth') {
          // 2. 检查属性变化：关注 'attribute' 类型的变更
          // 判断变化的属性名是否是 'style'，或者更具体地，是否与宽度相关
          // 获取发生属性变化的元素
          const element = change.range.start.nodeAfter || change.range.start.parent
          // 检查这个元素是否是 tableCell 或 table
          if (element.is('element', 'tableCell') || element.is('element', 'tableColumn')) {
            // 列宽调整
            allTableChanges.push(change)
            debounceTableChange(allTableChanges)
          }
        }
      })
    })
    // 只读模式，样式问题
    if (props.readonly) {
      editorInstance.sourceElement?.firstChild?.classList?.remove('ck-widget_selected')
    }
  })
}

// 设置对齐方式的方法
const setAlignment = (alignment = 'left') => {
  if (!editorInstance) {
    console.warn('编辑器实例尚未初始化')
    return
  }

  // 支持的对齐方式: left, right, center, justify
  const validAlignments = ['left', 'right', 'center', 'justify']
  if (!validAlignments.includes(alignment)) {
    console.warn(`不支持的对齐方式: ${alignment}，请使用: ${validAlignments.join(', ')}`)
    return
  }

  // 执行对齐命令
  editorInstance.execute('alignment', { value: alignment })
}

// 暴露方法供外部调用
defineExpose({
  setAlignment,
  getEditor: () => editorInstance
})
</script>
<style>
.ck.ck-powered-by {
  display: none !important;
  pointer-events: none !important;
  opacity: 0 !important;
}

.ck.ck-editor {
  display: flex;
  flex-direction: column;
  height: 100% !important;
  width: 100% !important;
}

.ck.ck-editor .ck.ck-editor__main {
  flex: 1;
  overflow: hidden;
  width: 100% !important;
}

.ck.ck-editor .ck.ck-editor__main .ck.ck-content {
  height: 100%;
  overflow: auto;
  width: 100% !important;
  max-width: none !important;
  margin: 0 !important;
  padding: 12px !important;
}

.ck.ck-editor .ck.ck-editor__main .ck-source-editing-area {
  height: 100%;
  overflow: auto;
}

.ck.ck-editor .ck.ck-toolbar.ck-toolbar_grouping > .ck-toolbar__items {
  flex-wrap: wrap;
}

.ck.ck-balloon-panel:has(.ck-toolbar__items:empty) {
  display: none;
}

/* 表格自适应宽度 */
.ck-content table {
  width: 100% !important;
  table-layout: auto !important;
}

/* 移除编辑器的默认最大宽度限制 */
.ck-content {
  max-width: none !important;
}

/* 确保内联编辑器占满容器宽度 */
.ck.ck-editor__editable_inline {
  width: 100% !important;
  max-width: none !important;
}

/* 表格的margin-top改小了，表格工具栏位置调整 - 让它更靠上 */
.ck.ck-balloon-panel:has(.ck-toolbar[aria-label='表格工具栏']) {
  transform: translateY(-58px) !important;
}

/* 悬浮提示信息位置调整 */
.ck.ck-balloon-panel.ck-tooltip:has(.ck-tooltip__text) {
  transform: translateY(0) !important;
}

/* 确保工具栏在表格正上方 */
.ck.ck-balloon-panel[data-ck-balloon-visible='true'] {
  position: absolute !important;
  top: auto !important;
  bottom: calc(100% + 8px) !important;
  left: 50% !important;
  transform: translateX(-50%) translateY(-5px) !important;
}
/* 显示表格form */
.ck.ck-balloon-panel:has(.ck-table-form.ck-table-properties-form) {
  display: block !important;
}
/* 隐藏左侧工具按钮 */
.ck.ck-block-toolbar-button {
  display: none !important;
}
/* 隐藏表格边框和阴影 */
.table-container .ck.ck-editor__editable.ck-focused:not(.ck-editor__nested-editable) {
  border: none;
  box-shadow: none;
}
</style>
